package dasregistry.ontology.browsing;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.Vector;

import org.biojava.bio.seq.io.ParseException;
import org.biojava.ontology.Ontology;
import org.biojava.ontology.Term;
import org.biojava.ontology.Triple;
import org.biojava.ontology.io.OboParser;

/**
 * @author Andreas Dr&auml;ger, Universit&auml;t T&uuml;bingen.
 * @since 1.8
 */
public class OBO2GraphViz {
 
	Ontology ontology;
	List<String> arcs;
	Set<Term> nodes;
 
	public OBO2GraphViz(String oboFileName, String ontoName,
			String ontoDescription, String root) throws ParseException,
			FileNotFoundException, IOException {
		
//		OboParser parser = new OboParser();
//		InputStream inStream = this.getClass().getResourceAsStream(
//				"/ontologies/" + oboFileName);
//		BufferedReader oboFile=new BufferedReader(new InputStreamReader(
//				inStream));
		OboParser parser = new OboParser();
		ontology = parser.parseOBO(new BufferedReader(new FileReader(oboFileName)), ontoName, ontoDescription);
		arcs = new Vector<String>();
		nodes = new HashSet<Term>();
		
		FileWriter fstream = new FileWriter("/Users/jw12/graphout.dot");
        BufferedWriter out = new BufferedWriter(fstream);
    
		traverse(ontology.getTerm(root));
		out.write("digraph \n");
		out.write(ontology.getName());
		out.write(" {\n");
//		for (Term t : nodes) {
//			out.write("  \n");
//			out.write(t.getName().replace(":", "")+"\n");
//			out.write(" [label=\""
//					+ lineBreaks(t.getDescription(), 18) + "\"];\n");
//		}
		for (String arc : arcs) {
			out.write("  \n");
			out.write(arc+"\n");
		}
		out.write("}\n");
		out.flush();
		out.close();
	}
 
	/**
	 * Inserts line breaks within the given string.
	 * 
	 * @param orig
	 * @param length
	 * @return
	 */
	private String lineBreaks(String orig, int length) {
		StringBuffer out = new StringBuffer();
		// Symol \u00e4 is a German umlaut a, a letter that will
		// normally not occur in our original Strings.
		String tmp = orig.replace("\\,", ",").replace(" ", " \u00e4");
		tmp = tmp.replace("-", "-\u00e4");
		String parts[] = tmp.contains("\u00e4") ? tmp.split("\u00e4")
				: new String[] { orig };
		for (int i = 0, curr = 0; i < parts.length; i++) {
			String part = parts[i];
			if ((part.length() + curr >= length)
					|| (i < parts.length - 1 && part.length()
							+ parts[i + 1].length() + curr >= length)) {
				out.append(part.trim());
				out.append("\\n");
				curr = 0;
			} else {
				out.append(part);
				curr += part.length();
			}
		}
		return out.toString();
	}
 
	private void traverse(Term subject) {
		Set<Triple> triples = ontology.getTriples(null, subject, null);
		String arc;
		for (Triple triple : triples) {
			//System.out.println("name="+triple.getName()+"|");
			nodes.add(triple.getSubject());
			//System.out.println("adding subject:"+triple.getSubject()+" "+triple.getDescription());
			nodes.add(triple.getObject());
			//System.out.println("adding object:"+triple.getObject()+" "+triple.getDescription());
			arc = triple.toString().replace(triple.getPredicate().getName(),"->").replace(":", "");
			if (!arcs.contains(arc))
				arcs.add(arc);
			traverse(triple.getSubject());
		}
	}
 
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		try {
			//"SO", "sequence ontology", "so.obo"
			new OBO2GraphViz("/Users/jw12/workspaceJune2009/dasregistry/resources/ontologies/biosapiens.obo", "BO", "description", "BS:00330");
		} catch (ParseException e) {
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
 
}
